/* hal_dma.h */
#ifndef __HAL_DMA_H__
#define __HAL_DMA_H__

#include "hal_common.h"
#include "hal_dma_requests.h"

typedef struct
{
    bool EnableMinorLoopOffset; /* do not enable it. */
    bool EnableContinuousLinkMode; /* schedule the controller when using multiple channels at the same time. */
    bool EnableKeepTransOnDebug;
} DMA_ControllerInit_Type;

void DMA_InitController(DMA_Type * base, DMA_ControllerInit_Type * init);
void DMA_SetChannelTrigger(DMA_Type * base, uint32_t channel, uint32_t dmamux);

typedef enum
{
    DMA_TransDataWidth_8b = 0u,
    DMA_TransDataWidth_16b = 1u,
    DMA_TransDataWidth_32b = 2u,
    DMA_TransDataWidth_16b_burst = 4u,
    DMA_TransDataWidth_32b_burst = 5u,
} DMA_TransDataWidth_Type;

typedef struct
{
    /* source addr. */
    uint32_t SourceAddr;
    int32_t  SourceAddrOffsetOnTrans; /* offset of source address after one bus transfer. */
    DMA_TransDataWidth_Type SourceTransDataWidth;
    //int32_t SourceAddrOffsetOnMinorLoop; /* offset of source address after one minor loop. */
    int32_t SourceAddrOffsetOnMajorLoop; /* offset of source address after one major loop. */

    /* dest addr. */
    uint32_t DestAddr;
    int32_t  DestAddrOffsetOnTrans;
    DMA_TransDataWidth_Type DestTransDataWidth;
    //int32_t  DestAddrOffsetOnMinorLoop;
    int32_t  DestAddrOffsetOnMajorLoop; /* offset of dest address after one major loop. */
    
    /* loops. */
    uint32_t MinorLoopByteCount;
    uint32_t MajorLoopCount;
    
    /* config. */
    bool EnableInterruptOnMajorLoopDone; /*!< Enable an interrupt when channel all trigger loop done. */
    bool EnableInterruptOnMajorLoopHalfDone; /*!< Enable an interrupt when half trigger loop done. */
    bool EnableInterruptOnMinorLoopDone; /*!< Enable an interrupt when one trigger loop done. */
    
    bool EnableAutoDisableChannelReqOnMajorLoopDone;
    
    //uint32_t MajorLoopCountReload;
    bool EnableReloadRamConf;

} DMA_ChannelTransStruct_Type;

void DMA_SetChannelTransStruct(DMA_Type * base, uint32_t channel, DMA_ChannelTransStruct_Type * cts);

void DMA_EnableChannelReqs(DMA_Type * base, uint32_t channels);
void DMA_DisableChannelReqs(DMA_Type * base, uint32_t channels);

uint32_t DMA_GetMajorLoopDoneChannels(DMA_Type * base);
void DMA_ClearMajorLoopDoneChannels(DMA_Type * base, uint32_t channels);

uint32_t DMA_GetMajorLoopHalfDoneChannels(DMA_Type * base);
void DMA_ClearMajorLoopHalfDoneChannels(DMA_Type * base, uint32_t channels);

uint32_t DMA_GetMinorLoopDoneChannels(DMA_Type * base);
void DMA_ClearMinorLoopDoneChannels(DMA_Type * base, uint32_t channels);

void DMA_DoSoftwareTriggerChannels(DMA_Type * base, uint32_t channels);



#endif /* __HAL_DMA_H__ */

